package game.util;

import java.util.ArrayList;
import java.util.List;

import com.sun.istack.internal.logging.Logger;

/**
 * Managing the table for the user action and computer reaction
 * 
 * @author Richard Gasztany
 * 
 */
public class Game {
    private static final Logger logger = Logger.getLogger(Game.class);

    private int computerPoint = 0;
    private int userPoint = 0;
    private List<Integer> table;

    /**
     * Initializing the game table
     * 
     * @param holeNumber
     *            number of holes
     * @return the game table
     */
    public List<Integer> initGameTable(int holeNumber, int stone) {
        holeNumber++;
        holeNumber *= 2;
        table = new ArrayList<Integer>();

        for (int i = 0; i < holeNumber; i++) {
            table.add(i, stone);
        }
        // user point
        table.set(holeNumber / 2 - 1, userPoint);

        // player point
        table.set(holeNumber - 1, computerPoint);

        logger.info("init table: " + table.toString());
        return table;
    }

    /**
     * Setting up the table after the user or computer choosing
     * 
     * @param actualTable
     *            current game table
     * @param col
     *            chosen hole/current game position
     * @param fogolyTabor
     *            detention where contains the stone
     * @return stateAfterStep={0-init,1-user free stepping,2-special stepping,3-end}
     */
    public int stepping(List<Integer> actualTable, int col, int fogolyTabor) {
        int stateAfterStep = 0;
        int actual = actualTable.get(col).intValue();
        int hovalepett = col + actual;
        boolean computerFreeStepp = false;

        logger.info("actualTable: " + actualTable.toString());
        actualTable.set(col, 0);

        // user free stepping
        if ((actual + col) == fogolyTabor) {
            // comp
            if (fogolyTabor == actualTable.size() - 1) {
                computerFreeStepp = true;
            } else {
                // user free stepping
                stateAfterStep = 1;
                logger.info("step table: " + actualTable.toString());
            }

        } else {
            // checking the another rule
            if (hovalepett < fogolyTabor && actualTable.get(hovalepett).intValue() == 0) {
                stateAfterStep = 2;
            }

        }
        logger.info("before general stepping: " + actualTable.toString());

        // changing the table
        for (int j = col + 1; j <= hovalepett; j++) {
            int index = j % actualTable.size();
            actualTable.set(index, actualTable.get(index).intValue() + 1);
        }
        logger.info("after general stepping :" + actualTable.toString());

        // special stone moving
        if (stateAfterStep == 2) {
            int szembenlevo = actualTable.size() - 2 - hovalepett;

            int x = actualTable.get(hovalepett).intValue();
            int y = actualTable.get(szembenlevo).intValue();

            actualTable.set(hovalepett, 0);
            actualTable.set(szembenlevo, 0);
            actualTable.set(fogolyTabor, actualTable.get(fogolyTabor).intValue() + x + y);
            logger.info("special stepping :" + actualTable.toString());

        }

        // checking the table
        boolean ending = true;
        // computer
        logger.info("ending cheking");
        if (fogolyTabor == actualTable.size() - 1) {
            for (int i = actualTable.size() / 2; i < actualTable.size() - 1; i++) {
                if (actualTable.get(i).intValue() != 0) {
                    logger.info("computer :" + i + " hole = 0");
                    ending = false;
                }
            }

            // user
        } else {
            for (int i = 0 / 2; i < actualTable.size() / 2 - 1; i++) {
                if (actualTable.get(i).intValue() != 0) {
                    logger.info("user :" + i + " hole = 0");
                    ending = false;
                }
            }
        }

        // cheking the game is finished
        if (ending) {
            logger.info("This is ending");
            stateAfterStep = 3;
        }
        if (computerFreeStepp) {
            logger.info("Computer free next stepping");
            computerStep(actualTable);
        }
        logger.info("stateAfterStep: " + stateAfterStep);
        return stateAfterStep;
    }

    /**
     * Simulate the computer stepping. Computer choosing the first not null hole.
     * 
     * @param actualTable
     *            current game table
     * 
     * @return stateAfterStep={0-init,1-user free stepping,2-special stepping,3-end}
     */
    public int computerStep(List<Integer> actualTable) {

        int computerStep = 0;
        for (int i = actualTable.size() / 2; i < actualTable.size() - 1; i++) {
            if (actualTable.get(i).intValue() != 0) {
                computerStep = i;
                break;
            }
        }
        int stateAfterStep = stepping(actualTable, computerStep, actualTable.size() - 1);

        return stateAfterStep;
    }

    /**
     * 
     * @param actualTable
     *            current game table
     * @param stateAfterStep
     *            ={0-init,1-user free stepping,2-special stepping,3-end}
     * @return JSON formatted table
     */
    public StringBuilder tableToJSon(List<Integer> actualTable, int stateAfterStep) {
        StringBuilder jsonResponse = new StringBuilder();
        jsonResponse.append("{");
        jsonResponse.append("\"state\":");

        jsonResponse.append("[");

        // changing the table for the UI
        for (int i = actualTable.size() - 1; i >= actualTable.size() / 2; i--) {
            jsonResponse.append(actualTable.get(i).intValue());
            jsonResponse.append(",");
        }
        for (int i = 0; i < actualTable.size() / 2; i++) {
            jsonResponse.append(actualTable.get(i).intValue());
            jsonResponse.append(",");

        }
        jsonResponse.deleteCharAt(jsonResponse.lastIndexOf(","));
        jsonResponse.append("]");
        jsonResponse.append(",\"stateAfterStep\":\"" + stateAfterStep + "\"");
        jsonResponse.append("}");

        return jsonResponse;
    }

}
